from usr.dtu.serial import Serial
from usr.dtu.configure import Config
from usr.dtu.common import Thread, Condition
from usr.dtu.clouds import CloudFactory
from usr.dtu.logging import getLogger

logger = getLogger(__name__)


class Dtu(object):

    def __init__(self, name):
        self.name = name
        self.config = Config()
        self.upload_thread = None
        self.download_threads = []

    def __repr__(self):
        return '<Dtu "{}">'.format(self.name)

    @property
    def clouds(self):
        __clouds__ = getattr(self, '__clouds__', None)
        if __clouds__ is None:
            __clouds__ = CloudFactory.create()
            setattr(self, '__clouds__', __clouds__)
        return __clouds__

    @property
    def serial(self):
        __serial__ = getattr(self, '__serial__', None)
        if __serial__ is None:
            __serial__ = Serial(**self.config['UART'])
            setattr(self, '__serial__', __serial__)
        return __serial__

    def run(self):
        self.serial.init()
        for cloud in self.clouds:
            cloud.init()
            thread = Thread(target=self.download_thread_worker, args=(cloud, ))
            thread.start()
            self.download_threads.append(thread)
        self.upload_thread = Thread(target=self.upload_thread_worker)
        logger.info('Dtu run successfully!')

    def download_thread_worker(self, cloud):
        while True:
            payload = cloud.recv()
            logger.info('down transfer msg: {}'.format(payload))
            self.serial.write(payload['data'])

    def upload_thread_worker(self):
        print('dtu start upload thread: {}'.format(self.upload_thread))
        while True:
            data = self.serial.read(1024)
            logger.info('up transfer msg: {}'.format(data))
            for cloud in self.clouds:
                try:
                    cloud.send(data)
                except Exception as e:
                    logger.error('cloud send error: {}'.format(e))
                    cloud.init()
